home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / shockab.zip / SUBS.QC < prev    next >
Text File  |  1996-10-08  |  7KB  |  353 lines

  1.  
  2.  
  3. void() SUB_Null = {};
  4.  
  5. void() SUB_Remove = {remove(self);};
  6.  
  7. void(vector org, vector vel) create_bubble;
  8.  
  9. void() CheckForDamage =
  10. {
  11. /* This is NOT the best way to do the damage, but i don't know how to do
  12.    in some other way. If you have any suggestions, tell me. */
  13.  
  14.     local float a,c;
  15.  
  16.     a = pointcontents(self.origin);
  17.  
  18.     if (a == CONTENT_EMPTY)
  19.         self.button0 = time + 0.5;
  20.  
  21.     if (self.button0 < time)
  22.     {
  23.         if (a == CONTENT_WATER)       // Drown'em
  24.         {
  25.             if (self.classname == "monster_fish")
  26.                 return;
  27.             if (self.classname == "monster_zombie")
  28.                 return;
  29.             c = pointcontents(self.absmax);
  30.             if (c == CONTENT_WATER)
  31.                 T_Damage(self,world,world,10); // Complete under water
  32.             else
  33.                 T_Damage(self,world,world,5); // Half under water
  34.         }
  35.         if (a == CONTENT_SLIME)       // Shrink'em
  36.             T_Damage(self,world,world,50);
  37.         if (a == CONTENT_LAVA)        // Crisp'em
  38.             T_Damage(self,world,world,100);
  39.         create_bubble(self.origin,'0 0 15');
  40.         self.button0 = time + 0.5;
  41.     }
  42. };
  43.  
  44. /*
  45. QuakeEd only writes a single float for angles (bad idea), so up and down are
  46. just constant angles.
  47. */
  48. vector() SetMovedir =
  49. {
  50.     if (self.angles == '0 -1 0')
  51.         self.movedir = '0 0 1';
  52.     else if (self.angles == '0 -2 0')
  53.         self.movedir = '0 0 -1';
  54.     else
  55.     {
  56.         makevectors (self.angles);
  57.         self.movedir = v_forward;
  58.     }
  59.     
  60.     self.angles = '0 0 0';
  61. };
  62.  
  63. /*
  64. ================
  65. InitTrigger
  66. ================
  67. */
  68. void() InitTrigger =
  69. {
  70. // trigger angles are used for one-way touches.  An angle of 0 is assumed
  71. // to mean no restrictions, so use a yaw of 360 instead.
  72.     if (self.angles != '0 0 0')
  73.         SetMovedir ();
  74.     self.solid = SOLID_TRIGGER;
  75.     setmodel (self, self.model);  // set size and link into world
  76.     self.movetype = MOVETYPE_NONE;
  77.     self.modelindex = 0;
  78.     self.model = "";
  79. };
  80.  
  81. /*
  82. =============
  83. SUB_CalcMove
  84.  
  85. calculate self.velocity and self.nextthink to reach dest from
  86. self.origin traveling at speed
  87. ===============
  88. */
  89. void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
  90. {
  91. local entity      stemp;
  92.     stemp = self;
  93.     self = ent;
  94.  
  95.     SUB_CalcMove (tdest, tspeed, func);
  96.     self = stemp;
  97. };
  98.  
  99. void(vector tdest, float tspeed, void() func) SUB_CalcMove =
  100. {
  101. local vector      vdestdelta;
  102. local float       len, traveltime;
  103.  
  104.     if (!tspeed)
  105.         objerror("No speed is defined!");
  106.  
  107.     self.think1 = func;
  108.     self.finaldest = tdest;
  109.     self.think = SUB_CalcMoveDone;
  110.  
  111.     if (tdest == self.origin)
  112.     {
  113.         self.velocity = '0 0 0';
  114.         self.nextthink = self.ltime + 0.1;
  115.         return;
  116.     }
  117.         
  118. // set destdelta to the vector needed to move
  119.     vdestdelta = tdest - self.origin;
  120.     
  121. // calculate length of vector
  122.     len = vlen (vdestdelta);
  123.     
  124. // divide by speed to get time to reach dest
  125.     traveltime = len / tspeed;
  126.  
  127.     if (traveltime < 0.1)
  128.     {
  129.         self.velocity = '0 0 0';
  130.         self.nextthink = self.ltime + 0.1;
  131.         return;
  132.     }
  133.     
  134. // set nextthink to trigger a think when dest is reached
  135.     self.nextthink = self.ltime + traveltime;
  136.  
  137. // scale the destdelta vector by the time spent traveling to get velocity
  138.     self.velocity = vdestdelta * (1/traveltime);    // qcc won't take vec/float   
  139. };
  140.  
  141. /*
  142. ============
  143. After moving, set origin to exact final destination
  144. ============
  145. */
  146. void()  SUB_CalcMoveDone =
  147. {
  148.     setorigin(self, self.finaldest);
  149.     self.velocity = '0 0 0';
  150.     self.nextthink = -1;
  151.     if (self.think1)
  152.         self.think1();
  153. };
  154.  
  155.  
  156. /*
  157. =============
  158. SUB_CalcAngleMove
  159.  
  160. calculate self.avelocity and self.nextthink to reach destangle from
  161. self.angles rotating 
  162.  
  163. The calling function should make sure self.think is valid
  164. ===============
  165. */
  166. void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
  167. {
  168. local entity            stemp;
  169.     stemp = self;
  170.     self = ent;
  171.     SUB_CalcAngleMove (destangle, tspeed, func);
  172.     self = stemp;
  173. };
  174.  
  175. void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
  176. {
  177. local vector      destdelta;
  178. local float       len, traveltime;
  179.  
  180.     if (!tspeed)
  181.         objerror("No speed is defined!");
  182.         
  183. // set destdelta to the vector needed to move
  184.     destdelta = destangle - self.angles;
  185.     
  186. // calculate length of vector
  187.     len = vlen (destdelta);
  188.     
  189. // divide by speed to get time to reach dest
  190.     traveltime = len / tspeed;
  191.  
  192. // set nextthink to trigger a think when dest is reached
  193.     self.nextthink = self.ltime + traveltime;
  194.  
  195. // scale the destdelta vector by the time spent traveling to get velocity
  196.     self.avelocity = destdelta * (1 / traveltime);
  197.     
  198.     self.think1 = func;
  199.     self.finalangle = destangle;
  200.     self.think = SUB_CalcAngleMoveDone;
  201. };
  202.  
  203. /*
  204. ============
  205. After rotating, set angle to exact final angle
  206. ============
  207. */
  208. void() SUB_CalcAngleMoveDone =
  209. {
  210.     self.angles = self.finalangle;
  211.     self.avelocity = '0 0 0';
  212.     self.nextthink = -1;
  213.     if (self.think1)
  214.         self.think1();
  215. };
  216.  
  217.  
  218. //=============================================================================
  219.  
  220. void() DelayThink =
  221. {
  222.     activator = self.enemy;
  223.     SUB_UseTargets ();
  224.     remove(self);
  225. };
  226.  
  227. /*
  228. ==============================
  229. SUB_UseTargets
  230.  
  231. the global "activator" should be set to the entity that initiated the firing.
  232.  
  233. If self.delay is set, a DelayedUse entity will be created that will actually
  234. do the SUB_UseTargets after that many seconds have passed.
  235.  
  236. Centerprints any self.message to the activator.
  237.  
  238. Removes all entities with a targetname that match self.killtarget,
  239. and removes them, so some events can remove other triggers.
  240.  
  241. Search for (string)targetname in all entities that
  242. match (string)self.target and call their .use function
  243.  
  244. ==============================
  245. */
  246. void() SUB_UseTargets =
  247. {
  248.     local entity t, stemp, otemp, act;
  249.  
  250. //
  251. // check for a delay
  252. //
  253.     if (self.delay)
  254.     {
  255.     // create a temp object to fire at a later time
  256.         t = spawn();
  257.         t.classname = "DelayedUse";
  258.         t.nextthink = time + self.delay;
  259.         t.think = DelayThink;
  260.         t.enemy = activator;
  261.         t.message = self.message;
  262.         t.killtarget = self.killtarget;
  263.         t.target = self.target;
  264.         return;
  265.     }
  266.     
  267.     
  268. //
  269. // print the message
  270. //
  271.     if (activator.classname == "player" && self.message != "")
  272.     {
  273.         centerprint (activator, self.message);
  274.         if (!self.noise)
  275.             sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
  276.     }
  277.  
  278. //
  279. // kill the killtagets
  280. //
  281.     if (self.killtarget)
  282.     {
  283.         t = world;
  284.         do
  285.         {
  286.             t = find (t, targetname, self.killtarget);
  287.             if (!t)
  288.                 return;
  289.             remove (t);
  290.         } while ( 1 );
  291.     }
  292.     
  293. //
  294. // fire targets
  295. //
  296.     if (self.target)
  297.     {
  298.         act = activator;
  299.         t = world;
  300.         do
  301.         {
  302.             t = find (t, targetname, self.target);
  303.             if (!t)
  304.             {
  305.                 return;
  306.             }
  307.             stemp = self;
  308.             otemp = other;
  309.             self = t;
  310.             other = stemp;
  311.             if (self.use != SUB_Null)
  312.             {
  313.                 if (self.use)
  314.                     self.use ();
  315.             }
  316.             self = stemp;
  317.             other = otemp;
  318.             activator = act;
  319.         } while ( 1 );
  320.     }
  321.     
  322.  
  323. };
  324.  
  325.  
  326. /*
  327.  
  328. in nightmare mode, all attack_finished times become 0
  329. some monsters refire twice automatically
  330.  
  331. */
  332.  
  333. void(float normal) SUB_AttackFinished =
  334. {
  335.     self.cnt = 0;           // refire count for nightmare
  336.     if (skill != 3)
  337.         self.attack_finished = time + normal;
  338. };
  339.  
  340. float (entity targ) visible;
  341.  
  342. void (void() thinkst) SUB_CheckRefire =
  343. {
  344.     if (skill != 3)
  345.         return;
  346.     if (self.cnt == 1)
  347.         return;
  348.     if (!visible (self.enemy))
  349.         return;
  350.     self.cnt = 1;
  351.     self.think = thinkst;
  352. };
  353.